package de.lgohlke.compress;

import org.junit.Assert;
import org.junit.Test;

/**
 * <p>Abstract CompressorTestAbstract class.</p>
 *
 * @author lars
 * @version $Id: $
 * @since 0.0.1
 */
public abstract class CompressorTestAbstract<T>
{
  protected T              RAW_NOT_WORTH_TO_COMPRESS;
  protected T              RAW_REALLY_WORTH_TO_COMPRESS;

  protected ICompressor<T> compressor;

  /**
   * <p>testNotWorthToCompress.</p>
   *
   * @param <T> a T object.
   */
  @Test
  public void testNotWorthToCompress()
  {
    CompressableValue<T> result = compressor.compress(RAW_NOT_WORTH_TO_COMPRESS);

    Assert.assertEquals(false, result.isCompressed());
    Assert.assertEquals(0D, compressor.savedSpace(result).computePercentageSaved(), 1D);
    Assert.assertEquals(RAW_NOT_WORTH_TO_COMPRESS, result.getValue());
  }

  /**
   * <p>testWorthToCompress.</p>
   */
  @Test
  public void testWorthToCompress()
  {
    CompressableValue<T> result = compressor.compress(RAW_REALLY_WORTH_TO_COMPRESS);

    Assert.assertEquals(true, result.isCompressed());
    Assert.assertTrue(0 < compressor.savedSpace(result).computePercentageSaved());
    Assert.assertNotSame(RAW_REALLY_WORTH_TO_COMPRESS, result.getValue());
  }

  /**
   * <p>testDecompressNotCompressed.</p>
   */
  @Test
  public void testDecompressNotCompressed()
  {
    CompressableValue<T> result = compressor.compress(RAW_NOT_WORTH_TO_COMPRESS);

    Assert.assertEquals(false, result.isCompressed());
    Assert.assertEquals(0D, compressor.savedSpace(result).computePercentageSaved(), 1D);
    assertEquals(RAW_NOT_WORTH_TO_COMPRESS, compressor.decompress(result));
  }

  /**
   * <p>testDecompressCompressed.</p>
   */
  @Test
  public void testDecompressCompressed()
  {
    CompressableValue<T> result = compressor.compress(RAW_REALLY_WORTH_TO_COMPRESS);

    Assert.assertEquals(true, result.isCompressed());
    Assert.assertTrue(0 < compressor.savedSpace(result).computePercentageSaved());
    assertEquals(RAW_REALLY_WORTH_TO_COMPRESS, compressor.decompress(result));
  }

  /**
   * <p>assertEquals.</p>
   *
   * @param expected a T object.
   * @param actual a T object.
   */
  protected void assertEquals(final T expected, final T actual)
  {
    Assert.assertEquals(expected, actual);
  }
}
